machine library and ESP32 reference



machine - functions related to the hardware

The machine module contains specific functions related to the hardware on a particular board. Most functions in this module allow to achieve direct and unrestricted access to and control of hardware blocks on a system (like CPU, timers, buses, etc.). Used incorrectly, this can lead to malfunction, lockups, crashes of your board, and in extreme cases, hardware damage. A note of callbacks used by functions and class methods of machine module: all these callbacks should be considered as executing in an interrupt context. This is true for both physical devices with IDs >= 0 and "virtual" devices with negative IDs like -1 (these "virtual" devices are still thin shims on top of real hardware and real hardware interrupts). See Writing interrupt handlers.

-- Reset related functions

machine.reset()
Resets the device in a manner similar to pushing the external RESET button.
machine.soft_reset()
Performs a soft reset of the interpreter, deleting all Python objects and resetting the Python heap. It tries to retain the method by which the user is connected to the MicroPython REPL (eg serial, USB, Wifi).
machine.reset_cause()
Get the reset cause. See constants for the possible return values.

-- Interrupt related functions

machine.disable_irq()
Disable interrupt requests. Returns the previous IRQ state which should be considered an opaque value. This return value should be passed to the enable_irq() function to restore interrupts to their original state, before disable_irq() was called.
machine.enable_irq(state)
Re-enable interrupt requests. The state parameter should be the value that was returned from the most recent call to the disable_irq() function.

-- Power related functions

machine.freq()
Returns CPU frequency in hertz.
machine.idle()
Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
machine.sleep()
Note This function is deprecated, use lightsleep() instead with no arguments.
machine.lightsleep([time_ms])
machine.deepsleep([time_ms])
Stops execution in an attempt to enter a low power state. If time_ms is specified then this will be the maximum time in milliseconds that the sleep will last for. Otherwise the sleep can last indefinitely. With or without a timout, execution may resume at any time if there are events that require processing. Such events, or wake sources, should be configured before sleeping, like Pin change or RTC timeout. The precise behaviour and power-saving capabilities of lightsleep and deepsleep is highly dependent on the underlying hardware, but the general properties are:
  • A lightsleep has full RAM and state retention. Upon wake execution is resumed from the point where the sleep was requested, with all subsystems operational.
  • A deepsleep may not retain RAM or any other state of the system (for example peripherals or network interfaces). Upon wake execution is resumed from the main script, similar to a hard or power-on reset. The reset_cause() function will return machine.DEEPSLEEP and this can be used to distinguish a deepsleep wake from other resets.
  • machine.wake_reason()
    Get the wake reason. See constants for the possible return values. Availability: ESP32, WiPy.

    -- Miscellaneous functions

    machine.unique_id()
    Returns a byte string with a unique identifier of a board/SoC. It will vary from a board/SoC instance to another, if underlying hardware allows. Length varies by hardware (so use substring of a full value if you expect a short ID). In some MicroPython ports, ID corresponds to the network MAC address.
    machine.time_pulse_us(pin, pulse_level, timeout_us=1000000, /)
    Time a pulse on the given pin, and return the duration of the pulse in microseconds. The pulse_level argument should be 0 to time a low pulse or 1 to time a high pulse. If the current input value of the pin is different to pulse_level, the function first (*) waits until the pin input becomes equal to pulse_level, then (**) times the duration that the pin is equal to pulse_level. If the pin is already equal to pulse_level then timing starts straight away. The function will return -2 if there was timeout waiting for condition marked (*) above, and -1 if there was timeout during the main measurement, marked (**) above. The timeout is the same for both cases and given by timeout_us (which is in microseconds).
    machine.rng()
    Return a 24-bit software generated random number. Availability: WiPy.

    Constants

    machine.IDLE
    machine.SLEEP
    machine.DEEPSLEEP
    IRQ wake values.
    machine.PWRON_RESET
    machine.HARD_RESET
    machine.WDT_RESET
    machine.DEEPSLEEP_RESET
    machine.SOFT_RESET
    Reset causes.
    machine.WLAN_WAKE
    machine.PIN_WAKE
    machine.RTC_WAKE
    Wake-up reasons.

    -- Classes

    class Pin - control I/O pins class Signal - control and sense external I/O devices class ADC - analog to digital conversion class UART - duplex serial communication bus class SPI - a Serial Peripheral Interface bus protocol (master side) class I2C - a two-wire serial protocol class RTC - real time clock class Timer - control hardware timers class WDT - watchdog timer class SD - secure digital memory card (cc3200 port only) class SDCard - secure digital memory card

    class Pin - control I/O pins

    A pin object is used to control I/O pins (also known as GPIO - general-purpose input/output). Pin objects are commonly associated with a physical pin that can drive an output voltage and read input voltages. The pin class has methods to set the mode of the pin (IN, OUT, etc) and methods to get and set the digital logic level. For analog control of a pin, see the ADC class. A pin object is constructed by using an identifier which unambiguously specifies a certain I/O pin. The allowed forms of the identifier and the physical pin that the identifier maps to are port-specific. Possibilities for the identifier are an integer, a string or a tuple with port and pin number. Usage Model: from machine import Pin # create an output pin on pin #0 p0 = Pin(0, Pin.OUT) # set the value low then high p0.value(0) p0.value(1) # create an input pin on pin #2, with a pull up resistor p2 = Pin(2, Pin.IN, Pin.PULL_UP) # read and print the pin value print(p2.value()) # reconfigure pin #0 in input mode p0.mode(p0.IN) # configure an irq callback p0.irq(lambda p:print(p))

    Constructors

    class machine.Pin(id, mode=-1, pull=-1, *, value, drive, alt)
    Access the pin peripheral (GPIO pin) associated with the given id. If additional arguments are given in the constructor then they are used to initialise the pin. Any settings that are not specified will remain in their previous state. The arguments are:
  • id is mandatory and can be an arbitrary object. Among possible value types are: int (an internal Pin identifier), str (a Pin name), and tuple (pair of [port, pin]).
  • mode specifies the pin mode, which can be one of:
    • Pin.IN - Pin is configured for input. If viewed as an output the pin is in high-impedance state.
    • Pin.OUT - Pin is configured for (normal) output.
    • Pin.OPEN_DRAIN - Pin is configured for open-drain output. Open-drain output works in the following way: if the output value is set to 0 the pin is active at a low level; if the output value is 1 the pin is in a high-impedance state. Not all ports implement this mode, or some might only on certain pins.
    • Pin.ALT - Pin is configured to perform an alternative function, which is port specific. For a pin configured in such a way any other Pin methods (except Pin.init()) are not applicable (calling them will lead to undefined, or a hardware-specific, result). Not all ports implement this mode.
    • Pin.ALT_OPEN_DRAIN - The Same as Pin.ALT, but the pin is configured as open-drain. Not all ports implement this mode.
  • pull specifies if the pin has a (weak) pull resistor attached, and can be one of:
    • None - No pull up or down resistor.
    • Pin.PULL_UP - Pull up resistor enabled.
    • Pin.PULL_DOWN - Pull down resistor enabled.
  • value is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial output pin value if given, otherwise the state of the pin peripheral remains unchanged.
  • drive specifies the output power of the pin and can be one of: Pin.LOW_POWER, Pin.MED_POWER or Pin.HIGH_POWER. The actual current driving capabilities are port dependent. Not all ports implement this argument.
  • alt specifies an alternate function for the pin and the values it can take are port dependent. This argument is valid only for Pin.ALT and Pin.ALT_OPEN_DRAIN modes. It may be used when a pin supports more than one alternate function. If only one pin alternate function is supported the this argument is not required. Not all ports implement this argument.
  • As specified above, the Pin class allows to set an alternate function for a particular pin, but it does not specify any further operations on such a pin. Pins configured in alternate-function mode are usually not used as GPIO but are instead driven by other hardware peripherals. The only operation supported on such a pin is re-initialising, by calling the constructor or Pin.init() method. If a pin that is configured in alternate-function mode is re-initialised with Pin.IN, Pin.OUT, or Pin.OPEN_DRAIN, the alternate function will be removed from the pin.

    Methods

    Pin.init(mode=-1, pull=-1, *, value, drive, alt)
    Re-initialise the pin using the given parameters. Only those arguments that are specified will be set. The rest of the pin peripheral state will remain unchanged. See the constructor documentation for details of the arguments. Returns None.
    Pin.value([x])
    This method allows to set and get the value of the pin, depending on whether the argument x is supplied or not. If the argument is omitted then this method gets the digital logic level of the pin, returning 0 or 1 corresponding to low and high voltage signals respectively. The behaviour of this method depends on the mode of the pin:
  • Pin.IN - The method returns the actual input value currently present on the pin.
  • Pin.OUT - The behaviour and return value of the method is undefined.
  • Pin.OPEN_DRAIN - If the pin is in state ‘0’ then the behaviour and return value of the method is undefined. Otherwise, if the pin is in state ‘1’, the method returns the actual input value currently present on the pin.
  • If the argument is supplied then this method sets the digital logic level of the pin. The argument x can be anything that converts to a boolean. If it converts to True, the pin is set to state ‘1’, otherwise it is set to state ‘0’. The behaviour of this method depends on the mode of the pin:
  • Pin.IN - The value is stored in the output buffer for the pin. The pin state does not change, it remains in the high-impedance state. The stored value will become active on the pin as soon as it is changed to Pin.OUT or Pin.OPEN_DRAIN mode.
  • Pin.OUT - The output buffer is set to the given value immediately.
  • Pin.OPEN_DRAIN - If the value is ‘0’ the pin is set to a low voltage state. Otherwise the pin is set to high-impedance state.
  • When setting the value this method returns None.
    Pin.__call__([x])
    Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin. It is equivalent to Pin.value([x]). See Pin.value() for more details.
    Pin.on()
    Set pin to "1" output level.
    Pin.off()
    Set pin to "0" output level.
    Pin.mode([mode])
    Get or set the pin mode. See the constructor documentation for details of the mode argument.
    Pin.pull([pull])
    Get or set the pin pull state. See the constructor documentation for details of the pull argument.
    Pin.drive([drive])
    Get or set the pin drive strength. See the constructor documentation for details of the drive argument. Not all ports implement this method. Availability: WiPy.
    Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), *, priority=1, wake=None, hard=False)
    Configure an interrupt handler to be called when the trigger source of the pin is active. If the pin mode is Pin.IN then the trigger source is the external value on the pin. If the pin mode is Pin.OUT then the trigger source is the output buffer of the pin. Otherwise, if the pin mode is Pin.OPEN_DRAIN then the trigger source is the output buffer for state ‘0’ and the external pin value for state ‘1’. The arguments are:
  • handler is an optional function to be called when the interrupt triggers. The handler must take exactly one argument which is the Pin instance.
  • trigger configures the event which can generate an interrupt. Possible values are:
  • Pin.IRQ_FALLING interrupt on falling edge.
  • Pin.IRQ_RISING interrupt on rising edge.
  • Pin.IRQ_LOW_LEVEL interrupt on low level.
  • Pin.IRQ_HIGH_LEVEL interrupt on high level.
  • These values can be OR’ed together to trigger on multiple events.
  • priority sets the priority level of the interrupt. The values it can take are port-specific, but higher values always represent higher priorities.
  • wake selects the power mode in which this interrupt can wake up the system. It can be machine.IDLE, machine.SLEEP or machine.DEEPSLEEP. These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.
  • hard if true a hardware interrupt is used. This reduces the delay between the pin change and the handler being called. Hard interrupt handlers may not allocate memory; see Writing interrupt handlers.
  • This method returns a callback object.

    Constants

    The following constants are used to configure the pin objects. Note that not all constants are available on all ports.
    Pin.IN
    Pin.OUT
    Pin.OPEN_DRAIN
    Pin.ALT
    Pin.ALT_OPEN_DRAIN
    Selects the pin mode.
    Pin.PULL_UP
    Pin.PULL_DOWN
    Pin.PULL_HOLD
    Selects whether there is a pull up/down resistor. Use the value None for no pull.
    Pin.LOW_POWER
    Pin.MED_POWER
    Pin.HIGH_POWER
    Selects the pin drive strength.
    Pin.IRQ_FALLING
    Pin.IRQ_RISING
    Pin.IRQ_LOW_LEVEL
    Pin.IRQ_HIGH_LEVEL
    Selects the IRQ trigger type.

    class Signal - control and sense external I/O devices

    The Signal class is a simple extension of the Pin class. Unlike Pin, which can be only in "absolute" 0 and 1 states, a Signal can be in "asserted" (on) or "deasserted" (off) states, while being inverted (active-low) or not. In other words, it adds logical inversion support to Pin functionality. While this may seem a simple addition, it is exactly what is needed to support wide array of simple digital devices in a way portable across different boards, which is one of the major MicroPython goals. Regardless of whether different users have an active-high or active-low LED, a normally open or normally closed relay - you can develop a single, nicely looking application which works with each of them, and capture hardware configuration differences in few lines in the config file of your app. Example: from machine import Pin, Signal # Suppose you have an active-high LED on pin 0 led1_pin = Pin(0, Pin.OUT) # ... and active-low LED on pin 1 led2_pin = Pin(1, Pin.OUT) # Now to light up both of them using Pin class, you'll need to set # them to different values led1_pin.value(1) led2_pin.value(0) # Signal class allows to abstract away active-high/active-low # difference led1 = Signal(led1_pin, invert=False) led2 = Signal(led2_pin, invert=True) # Now lighting up them looks the same led1.value(1) led2.value(1) # Even better: led1.on() led2.on() Following is the guide when Signal vs Pin should be used:
  • Use Signal: If you want to control a simple on/off (including software PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or read simple binary sensors, like normally open or normally closed buttons, pulled high or low, Reed switches, moisture/flame detectors, etc. etc. Summing up, if you have a real physical device/sensor requiring GPIO access, you likely should use a Signal.
  • Use Pin: If you implement a higher-level protocol or bus to communicate with more complex devices.
  • The split between Pin and Signal come from the usecases above and the architecture of MicroPython: Pin offers the lowest overhead, which may be important when bit-banging protocols. But Signal adds additional flexibility on top of Pin, at the cost of minor overhead (much smaller than if you implemented active-high vs active-low device differences in Python manually!). Also, Pin is a low-level object which needs to be implemented for each support board, while Signal is a high-level object which comes for free once Pin is implemented. If in doubt, give the Signal a try! Once again, it is offered to save developers from the need to handle unexciting differences like active-low vs active-high signals, and allow other users to share and enjoy your application, instead of being frustrated by the fact that it doesn’t work for them simply because their LEDs or relays are wired in a slightly different way.

    Constructors

    class machine.Signal(pin_obj, invert=False)
    class machine.Signal(pin_arguments..., *, invert=False)
    Create a Signal object. There’re two ways to create it:
  • By wrapping existing Pin object - universal method which works for any board.
  • By passing required Pin parameters directly to Signal constructor, skipping the need to create intermediate Pin object. Available on many, but not all boards.
  • The arguments are:
  • pin_obj is existing Pin object.
  • pin_arguments are the same arguments as can be passed to Pin constructor.
  • invert - if True, the signal will be inverted (active low).
  • Methods

    Signal.value([x])
    This method allows to set and get the value of the signal, depending on whether the argument x is supplied or not. If the argument is omitted then this method gets the signal level, 1 meaning signal is asserted (active) and 0 - signal inactive. If the argument is supplied then this method sets the signal level. The argument x can be anything that converts to a boolean. If it converts to True, the signal is active, otherwise it is inactive. Correspondence between signal being active and actual logic level on the underlying pin depends on whether signal is inverted (active-low) or not. For non-inverted signal, active status corresponds to logical 1, inactive - to logical 0. For inverted/active-low signal, active status corresponds to logical 0, while inactive - to logical 1.
    Signal.on()
    Activate signal.
    Signal.off()
    Deactivate signal.

    class ADC - analog to digital conversion

    The ADC class provides an interface to analog-to-digital convertors, and represents a single endpoint that can sample a continuous voltage and convert it to a discretised value. Example usage: import machine adc = machine.ADC(pin) # create an ADC object acting on a pin val = adc.read_u16() # read a raw analog value in the range 0-65535

    Constructors

    class machine.ADC(id)
    Access the ADC associated with a source identified by id. This id may be an integer (usually specifying a channel number), a Pin object, or other value supported by the underlying machine.

    Methods

    ADC.read_u16()
    Take an analog reading and return an integer in the range 0-65535. The return value represents the raw reading taken by the ADC, scaled such that the minimum value is 0 and the maximum value is 65535.

    class UART - duplex serial communication bus

    UART implements the standard UART/USART duplex serial communications protocol. At the physical level it consists of 2 lines: RX and TX. The unit of communication is a character (not to be confused with a string character) which can be 8 or 9 bits wide. UART objects can be created and initialised using: from machine import UART uart = UART(1, 9600) # init with given baudrate uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters Supported parameters differ on a board: Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With parity=None, only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits are supported. WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2. A UART object acts like a stream object and reading and writing is done using the standard stream methods: uart.read(10) # read 10 characters, returns a bytes object uart.read() # read all available characters uart.readline() # read a line uart.readinto(buf) # read and store into the given buffer uart.write('abc') # write the 3 characters

    Constructors

    class machine.UART(id, ...)
    Construct a UART object of the given id.

    Methods

    UART.init(baudrate=9600, bits=8, parity=None, stop=1, *, ...)
    Initialise the UART bus with the given parameters:
  • baudrate is the clock rate.
  • bits is the number of bits per character, 7, 8 or 9.
  • parity is the parity, None, 0 (even) or 1 (odd).
  • stop is the number of stop bits, 1 or 2.
  • Additional keyword-only parameters that may be supported by a port are:
  • tx specifies the TX pin to use.
  • rx specifies the RX pin to use.
  • txbuf specifies the length in characters of the TX buffer.
  • rxbuf specifies the length in characters of the RX buffer.
  • timeout specifies the time to wait for the first character (in ms).
  • timeout_char specifies the time to wait between characters (in ms).
  • invert specifies which lines to invert.
  • On the WiPy only the following keyword-only parameter is supported:
  • pins is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order). Any of the pins can be None if one wants the UART to operate with limited functionality. If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. When no pins are given, then the default set of TX and RX pins is taken, and hardware flow control will be disabled. If pins is None, no pin assignment will be made.
  • UART.deinit()
    Turn off the UART bus.
    UART.any()
    Returns an integer counting the number of characters that can be read without blocking. It will return 0 if there are no characters available and a positive number if there are characters. The method may return 1 even if there is more than one character available for reading. For more sophisticated querying of available characters use select.poll: poll = select.poll() poll.register(uart, select.POLLIN) poll.poll(timeout)
    UART.read([nbytes])
    Read characters. If nbytes is specified then read at most that many bytes, otherwise read as much data as possible. It may return sooner if a timeout is reached. The timeout is configurable in the constructor. Return value: a bytes object containing the bytes read in. Returns None on timeout.
    UART.readinto(buf[, nbytes])
    Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most len(buf) bytes. It may return sooner if a timeout is reached. The timeout is configurable in the constructor. Return value: number of bytes read and stored into buf or None on timeout.
    UART.readline()
    Read a line, ending in a newline character. It may return sooner if a timeout is reached. The timeout is configurable in the constructor. Return value: the line read or None on timeout.
    UART.write(buf)
    Write the buffer of bytes to the bus. Return value: number of bytes written or None on timeout.
    UART.sendbreak()
    Send a break condition on the bus. This drives the bus low for a duration longer than required for a normal transmission of a character.
    UART.irq(trigger, priority=1, handler=None, wake=machine.IDLE)
    Create a callback to be triggered when data is received on the UART.
  • trigger can only be UART.RX_ANY
  • priority level of the interrupt. Can take values in the range 1-7. Higher values represent higher priorities.
  • handler an optional function to be called when new characters arrive.
  • wake can only be machine.IDLE.
  • Note The handler will be called whenever any of the following two conditions are met:
  • 8 new characters have been received.
  • At least 1 new character is waiting in the Rx buffer and the Rx line has been silent for the duration of 1 complete frame.
  • This means that when the handler function is called there will be between 1 to 8 characters waiting. Returns an irq object. Availability: WiPy.

    Constants

    UART.RX_ANY
    IRQ trigger sources Availability: WiPy.

    class SPI - a Serial Peripheral Interface bus protocol (master side)

    SPI is a synchronous serial protocol that is driven by a master. At the physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices can share the same bus. Each device should have a separate, 4th signal, SS (Slave Select), to select a particular device on a bus with which communication takes place. Management of an SS signal should happen in user code (via machine.Pin class).

    Constructors

    class machine.SPI(id, ...)
    Construct an SPI object on the given bus, id. Values of id depend on a particular port and its hardware. Values 0, 1, etc. are commonly used to select hardware SPI block #0, #1, etc. Value -1 can be used for bitbanging (software) implementation of SPI (if supported by a port). With no additional parameters, the SPI object is created but not initialised (it has the settings from the last initialisation of the bus, if any). If extra arguments are given, the bus is initialised. See init for parameters of initialisation.

    Methods

    SPI.init(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))
    Initialise the SPI bus with the given parameters:
  • baudrate is the SCK clock rate.
  • polarity can be 0 or 1, and is the level the idle clock line sits at.
  • phase can be 0 or 1 to sample data on the first or second clock edge respectively.
  • bits is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware.
  • firstbit can be SPI.MSB or SPI.LSB.
  • sck, mosi, miso are pins (machine.Pin) objects to use for bus signals. For most hardware SPI blocks (as selected by id parameter to the constructor), pins are fixed and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver (id = -1).
  • pins - WiPy port doesn’t sck, mosi, miso arguments, and instead allows to specify them as a tuple of pins parameter.
  • In the case of hardware SPI the actual clock frequency may be lower than the requested baudrate. This is dependant on the platform hardware. The actual rate may be determined by printing the SPI object.
    SPI.deinit()
    Turn off the SPI bus.
    SPI.read(nbytes, write=0x00)
    Read a number of bytes specified by nbytes while continuously writing the single byte given by write. Returns a bytes object with the data that was read.
    SPI.readinto(buf, write=0x00)
    Read into the buffer specified by buf while continuously writing the single byte given by write. Returns None. Note: on WiPy this function returns the number of bytes read.
    SPI.write(buf)
    Write the bytes contained in buf. Returns None. Note: on WiPy this function returns the number of bytes written.
    SPI.write_readinto(write_buf, read_buf)
    Write the bytes from write_buf while reading into read_buf. The buffers can be the same or different, but both buffers must have the same length. Returns None. Note: on WiPy this function returns the number of bytes written.

    Constants

    SPI.MASTER
    for initialising the SPI bus to master; this is only used for the WiPy
    SPI.MSB
    set the first bit to be the most significant bit
    SPI.LSB
    set the first bit to be the least significant bit

    class I2C - a two-wire serial protocol

    I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively. I2C objects are created attached to a specific bus. They can be initialised when created, or initialised later on. Printing the I2C object gives you information about its configuration. Example usage: from machine import I2C i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz # depending on the port, extra parameters may be required # to select the peripheral and/or pins to use i2c.scan() # scan for slaves, returning a list of 7-bit addresses i2c.writeto(42, b'123') # write 3 bytes to slave with 7-bit address 42 i2c.readfrom(42, 4) # read 4 bytes from slave with 7-bit address 42 i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of slave 42, # starting at memory-address 8 in the slave i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42 # starting at address 2 in the slave

    Constructors

    class machine.I2C(id=-1, *, scl, sda, freq=400000)
    Construct and return a new I2C object using the following parameters:
  • id identifies a particular I2C peripheral. The default value of -1 selects a software implementation of I2C which can work (in most cases) with arbitrary pins for SCL and SDA. If id is -1 then scl and sda must be specified. Other allowed values for id depend on the particular port/board, and specifying scl and sda may or may not be required or allowed in this case.
  • scl should be a pin object specifying the pin to use for SCL.
  • sda should be a pin object specifying the pin to use for SDA.
  • freq should be an integer which sets the maximum frequency for SCL.
  • -- General Methods

    I2C.init(scl, sda, *, freq=400000)
    Initialise the I2C bus with the given arguments:
  • scl is a pin object for the SCL line
  • sda is a pin object for the SDA line
  • freq is the SCL clock rate
  • I2C.deinit()
    Turn off the I2C bus. Availability: WiPy.
    I2C.scan()
    Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond. A device responds if it pulls the SDA line low after its address (including a write bit) is sent on the bus.

    -- Primitive I2C operations

    The following methods implement the primitive I2C master bus operations and can be combined to make any I2C transaction. They are provided if you need more control over the bus, otherwise the standard methods (see below) can be used. These methods are available on software I2C only.
    I2C.start()
    Generate a START condition on the bus (SDA transitions to low while SCL is high).
    I2C.stop()
    Generate a STOP condition on the bus (SDA transitions to high while SCL is high).
    I2C.readinto(buf, nack=True, /)
    Reads bytes from the bus and stores them into buf. The number of bytes read is the length of buf. An ACK will be sent on the bus after receiving all but the last byte. After the last byte is received, if nack is true then a NACK will be sent, otherwise an ACK will be sent (and in this case the slave assumes more bytes are going to be read in a later call).
    I2C.write(buf)
    Write the bytes from buf to the bus. Checks that an ACK is received after each byte and stops transmitting the remaining bytes if a NACK is received. The function returns the number of ACKs that were received.

    -- Standard bus operations

    The following methods implement the standard I2C master read and write operations that target a given slave device.
    I2C.readfrom(addr, nbytes, stop=True, /)
    Read nbytes from the slave specified by addr. If stop is true then a STOP condition is generated at the end of the transfer. Returns a bytes object with the data read.
    I2C.readfrom_into(addr, buf, stop=True, /)
    Read into buf from the slave specified by addr. The number of bytes read will be the length of buf. If stop is true then a STOP condition is generated at the end of the transfer. The method returns None.
    I2C.writeto(addr, buf, stop=True, /)
    Write the bytes from buf to the slave specified by addr. If a NACK is received following the write of a byte from buf then the remaining bytes are not sent. If stop is true then a STOP condition is generated at the end of the transfer, even if a NACK is received. The function returns the number of ACKs that were received.
    I2C.writevto(addr, vector, stop=True, /)
    Write the bytes contained in vector to the slave specified by addr. vector should be a tuple or list of objects with the buffer protocol. The addr is sent once and then the bytes from each object in vector are written out sequentially. The objects in vector may be zero bytes in length in which case they don’t contribute to the output. If a NACK is received following the write of a byte from one of the objects in vector then the remaining bytes, and any remaining objects, are not sent. If stop is true then a STOP condition is generated at the end of the transfer, even if a NACK is received. The function returns the number of ACKs that were received.

    -- Memory operations

    Some I2C devices act as a memory device (or set of registers) that can be read from and written to. In this case there are two addresses associated with an I2C transaction: the slave address and the memory address. The following methods are convenience functions to communicate with such devices.
    I2C.readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)
    Read nbytes from the slave specified by addr starting from the memory address specified by memaddr. The argument addrsize specifies the address size in bits. Returns a bytes object with the data read.
    I2C.readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)
    Read into buf from the slave specified by addr starting from the memory address specified by memaddr. The number of bytes read is the length of buf. The argument addrsize specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits). The method returns None.
    I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)
    Write buf to the slave specified by addr starting from the memory address specified by memaddr. The argument addrsize specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits). The method returns None.

    class RTC - real time clock

    The RTC is and independent clock that keeps track of the date and time. Example usage: rtc = machine.RTC() rtc.init((2014, 5, 1, 4, 13, 0, 0, 0)) print(rtc.now())

    Constructors

    class machine.RTC(id=0, ...)
    Create an RTC object. See init for parameters of initialization.

    Methods

    RTC.init(datetime)
    Initialise the RTC. Datetime is a tuple of the form:
    (year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])
    RTC.now()
    Get get the current datetime tuple.
    RTC.deinit()
    Resets the RTC to the time of January 1, 2015 and starts running it again.
    RTC.alarm(id, time, *, repeat=False)
    Set the RTC alarm. Time might be either a millisecond value to program the alarm to current time + time_in_ms in the future, or a datetimetuple. If the time passed is in milliseconds, repeat can be set to True to make the alarm periodic.
    RTC.alarm_left(alarm_id=0)
    Get the number of milliseconds left before the alarm expires.
    RTC.cancel(alarm_id=0)
    Cancel a running alarm.
    RTC.irq(*, trigger, handler=None, wake=machine.IDLE)
    Create an irq object triggered by a real time clock alarm.
  • trigger must be RTC.ALARM0
  • handler is the function to be called when the callback is triggered.
  • wake specifies the sleep mode from where this interrupt can wake up the system.
  • Constants

    RTC.ALARM0
    irq trigger source

    class Timer - control hardware timers

    Hardware timers deal with timing of periods and events. Timers are perhaps the most flexible and heterogeneous kind of hardware in MCUs and SoCs, differently greatly from a model to a model. MicroPython’s Timer class defines a baseline operation of executing a callback with a given period (or once after some delay), and allow specific boards to define more non-standard behavior (which thus won’t be portable to other boards). See discussion of important constraints on Timer callbacks. Note Memory can’t be allocated inside irq handlers (an interrupt) and so exceptions raised within a handler don’t give much information. See micropython.alloc_emergency_exception_buf() for how to get around this limitation. If you are using a WiPy board please refer to machine.TimerWiPy instead of this class.

    Constructors

    class machine.Timer(id, ...)
    Construct a new timer object of the given id. Id of -1 constructs a virtual timer (if supported by a board).

    Methods

    Timer.init(*, mode=Timer.PERIODIC, period=-1, callback=None)
    Initialise the timer. Example: tim.init(period=100) # periodic with 100ms period tim.init(mode=Timer.ONE_SHOT, period=1000) # one shot firing after 1000ms Keyword arguments:
  • mode can be one of:
    • Timer.ONE_SHOT - The timer runs once until the configured period of the channel expires.
    • Timer.PERIODIC - The timer runs periodically at the configured frequency of the channel.
  • Timer.deinit()
    Deinitialises the timer. Stops the timer, and disables the timer peripheral.

    Constants

    Timer.ONE_SHOT
    Timer.PERIODIC
    Timer operating mode.

    class WDT - watchdog timer

    The WDT is used to restart the system when the application crashes and ends up into a non recoverable state. Once started it cannot be stopped or reconfigured in any way. After enabling, the application must "feed" the watchdog periodically to prevent it from expiring and resetting the system. Example usage: from machine import WDT wdt = WDT(timeout=2000) # enable it with a timeout of 2s wdt.feed() Availability of this class: pyboard, WiPy.

    Constructors

    class machine.WDT(id=0, timeout=5000)
    Create a WDT object and start it. The timeout must be given in seconds and the minimum value that is accepted is 1 second. Once it is running the timeout cannot be changed and the WDT cannot be stopped either.

    Methods

    wdt.feed()
    Feed the WDT to prevent it from resetting the system. The application should place this call in a sensible place ensuring that the WDT is only fed after verifying that everything is functioning correctly.

    class SD - secure digital memory card (cc3200 port only)

    Warning This is a non-standard class and is only available on the cc3200 port. The SD card class allows to configure and enable the memory card module of the WiPy and automatically mount it as /sd as part of the file system. There are several pin combinations that can be used to wire the SD card socket to the WiPy and the pins used can be specified in the constructor. Please check the pinout and alternate functions table. for more info regarding the pins which can be remapped to be used with a SD card. Example usage: from machine import SD import os # clk cmd and dat0 pins must be passed along with # their respective alternate functions sd = machine.SD(pins=('GP10', 'GP11', 'GP15')) os.mount(sd, '/sd') # do normal file operations

    Constructors

    class machine.SD(id, ...)
    Create a SD card object. See init() for parameters if initialization.

    Methods

    SD.init(id=0, pins=('GP10', 'GP11', 'GP15'))
    Enable the SD card. In order to initialize the card, give it a 3-tuple: (clk_pin, cmd_pin, dat0_pin).
    SD.deinit()
    Disable the SD card.

    class SDCard - secure digital memory card

    SD cards are one of the most common small form factor removable storage media. SD cards come in a variety of sizes and physical form factors. MMC cards are similar removable storage devices while eMMC devices are electrically similar storage devices designed to be embedded into other systems. All three form share a common protocol for communication with their host system and high-level support looks the same for them all. As such in MicroPython they are implemented in a single class called machine.SDCard . Both SD and MMC interfaces support being accessed with a variety of bus widths. When being accessed with a 1-bit wide interface they can be accessed using the SPI protocol. Different MicroPython hardware platforms support different widths and pin configurations but for most platforms there is a standard configuration for any given hardware. In general constructing an SDCard object with without passing any parameters will initialise the interface to the default card slot for the current hardware. The arguments listed below represent the common arguments that might need to be set in order to use either a non-standard slot or a non-standard pin assignment. The exact subset of arguments supported will vary from platform to platform.
    class machine.SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None)
    This class provides access to SD or MMC storage cards using either a dedicated SD/MMC interface hardware or through an SPI channel. The class implements the block protocol defined by uos.AbstractBlockDev. This allows the mounting of an SD card to be as simple as: uos.mount(machine.SDCard(), "/sd") The constructor takes the following parameters:
  • slot selects which of the available interfaces to use. Leaving this unset will select the default interface.
  • width selects the bus width for the SD/MMC interface.
  • cd can be used to specify a card-detect pin.
  • wp can be used to specify a write-protect pin.
  • sck can be used to specify an SPI clock pin.
  • miso can be used to specify an SPI miso pin.
  • mosi can be used to specify an SPI mosi pin.
  • cs can be used to specify an SPI chip select pin.
  • -- Implementation-specific details

    Different implementations of the SDCard class on different hardware support varying subsets of the options above.

    .. PyBoard

    The standard PyBoard has just one slot. No arguments are necessary or supported.

    .. ESP32

    The ESP32 provides two channels of SD/MMC hardware and also supports access to SD Cards through either of the two SPI ports that are generally available to the user. As a result the slot argument can take a value between 0 and 3, inclusive. Slots 0 and 1 use the built-in SD/MMC hardware while slots 2 and 3 use the SPI ports. Slot 0 supports 1, 4 or 8-bit wide access while slot 1 supports 1 or 4-bit access; the SPI slots only support 1-bit access.
    Note Slot 0 is used to communicate with on-board flash memory on most ESP32 modules and so will be unavailable to the user. Note Most ESP32 modules that provide an SD card slot using the dedicated hardware only wire up 1 data pin, so the default value for width is 1.
    The pins used by the dedicated SD/MMC hardware are fixed. The pins used by the SPI hardware can be reassigned.
    Note If any of the SPI signals are remapped then all of the SPI signals will pass through a GPIO multiplexer unit which can limit the performance of high frequency signals. Since the normal operating speed for SD cards is 40MHz this can cause problems on some cards.
    The default (and preferred) pin assignment are as follows:
    Slot 0 1 2 3
    Signal Pin Pin Pin Pin
    sck 6 14 18 14
    cmd 11 15    
    cs     5 15
    miso     19 12
    mosi     23 13
    D0 7 2    
    D1 8 4    
    D2 9 12    
    D3 10 13    
    D4 16      
    D5 17      
    D6 5      
    D7 18      

    .. cc3200

    You can set the pins used for SPI access by passing a tuple as the pins argument. Note: The current cc3200 SD card implementation names the this class machine.SD rather than machine.SDCard .

    Quick reference for the ESP32

    ESP32 board The Espressif ESP32 Development Board (image attribution: Adafruit). Below is a quick reference for ESP32-based boards. If it is your first time working with this board it may be useful to get an overview of the microcontroller:
  • General information about the ESP32 port
  • Getting started with MicroPython on the ESP32

    -- Installing MicroPython

    See the corresponding section of tutorial: Getting started with MicroPython on the ESP32. It also includes a troubleshooting subsection.

    -- General board control

    The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200. Tab-completion is useful to find out what methods an object has. Paste mode (ctrl-E) is useful to paste a large slab of Python code into the REPL. The machine module: import machine machine.freq() # get the current frequency of the CPU machine.freq(240000000) # set the CPU frequency to 240 MHz The esp module: import esp esp.osdebug(None) # turn off vendor O/S debugging messages esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0) # low level methods to interact with flash storage esp.flash_size() esp.flash_user_start() esp.flash_erase(sector_no) esp.flash_write(byte_offset, buffer) esp.flash_read(byte_offset, buffer) The esp32 module: import esp32 esp32.hall_sensor() # read the internal hall sensor esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit esp32.ULP() # access to the Ultra-Low-Power Co-processor Note that the temperature sensor in the ESP32 will typically read higher than ambient due to the IC getting warm while it runs. This effect can be minimised by reading the temperature sensor immediately after waking up from sleep.

    -- Networking

    The network module: import network wlan = network.WLAN(network.STA_IF) # create station interface wlan.active(True) # activate the interface wlan.scan() # scan for access points wlan.isconnected() # check if the station is connected to an AP wlan.connect('essid', 'password') # connect to an AP wlan.config('mac') # get the interface's MAC address wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses ap = network.WLAN(network.AP_IF) # create access-point interface ap.config(essid='ESP-AP') # set the ESSID of the access point ap.config(max_clients=10) # set how many clients can connect to the network ap.active(True) # activate the interface A useful function for connecting to your local WiFi network is: def do_connect(): import network wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('essid', 'password') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) Once the network is established the socket module can be used to create and use TCP/UDP sockets as usual, and the urequests module for convenient HTTP requests.

    -- Delay and timing

    Use the time module: import time time.sleep(1) # sleep for 1 second time.sleep_ms(500) # sleep for 500 milliseconds time.sleep_us(10) # sleep for 10 microseconds start = time.ticks_ms() # get millisecond counter delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference

    -- Timers

    Virtual (RTOS-based) timers are supported. Use the machine.Timer class with timer ID of -1: from machine import Timer tim = Timer(-1) tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1)) tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2)) The period is in milliseconds.

    -- Pins and GPIO

    Use the machine.Pin class: from machine import Pin p0 = Pin(0, Pin.OUT) # create output pin on GPIO0 p0.on() # set pin to "on" (high) level p0.off() # set pin to "off" (low) level p0.value(1) # set pin to on/high p2 = Pin(2, Pin.IN) # create input pin on GPIO2 print(p2.value()) # get value, 0 or 1 p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39. These correspond to the actual GPIO pin numbers of ESP32 chip. Note that many end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). For mapping between board logical pins and physical chip pins consult your board documentation. Notes:
  • Pins 1 and 3 are REPL UART TX and RX respectively
  • Pins 6, 7, 8, 11, 16, and 17 are used for connecting the embedded flash, and are not recommended for other uses
  • Pins 34-39 are input only, and also do not have internal pull-up resistors
  • The pull value of some pins can be set to Pin.PULL_HOLD to reduce power consumption during deepsleep.
  • -- PWM (pulse width modulation)

    PWM can be enabled on all output-enabled pins. The base frequency can range from 1Hz to 40MHz but there is a tradeoff; as the base frequency increases the duty resolution decreases. See LED Control for more details. Use the machine.PWM class: from machine import Pin, PWM pwm0 = PWM(Pin(0)) # create PWM object from a pin pwm0.freq() # get current frequency pwm0.freq(1000) # set frequency pwm0.duty() # get current duty cycle pwm0.duty(200) # set duty cycle pwm0.deinit() # turn off PWM on the pin pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go

    -- ADC (analog to digital conversion)

    On the ESP32 ADC functionality is available on Pins 32-39. Note that, when using the default configuration, input voltages on the ADC pin must be between 0.0v and 1.0v (anything above 1.0v will just read as 4095). Attenuation must be applied in order to increase this usable voltage range. Use the machine.ADC class: from machine import ADC adc = ADC(Pin(32)) # create ADC object on ADC pin adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v) adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511) adc.read() # read value using the newly configured attenuation and width ESP32 specific ADC class method reference:
    ADC.atten(attenuation)
    This method allows for the setting of the amount of attenuation on the input of the ADC. This allows for a wider possible input voltage range, at the cost of accuracy (the same number of bits now represents a wider range). The possible attenuation options are:
  • ADC.ATTN_0DB: 0dB attenuation, gives a maximum input voltage of 1.00v - this is the default configuration
  • ADC.ATTN_2_5DB: 2.5dB attenuation, gives a maximum input voltage of approximately 1.34v
  • ADC.ATTN_6DB: 6dB attenuation, gives a maximum input voltage of approximately 2.00v
  • ADC.ATTN_11DB: 11dB attenuation, gives a maximum input voltage of approximately 3.6v
  • Warning Despite 11dB attenuation allowing for up to a 3.6v range, note that the absolute maximum voltage rating for the input pins is 3.6v, and so going near this boundary may be damaging to the IC!
    ADC.width(width)
    This method allows for the setting of the number of bits to be utilised and returned during ADC reads. Possible width options are:
  • ADC.WIDTH_9BIT: 9 bit data
  • ADC.WIDTH_10BIT: 10 bit data
  • ADC.WIDTH_11BIT: 11 bit data
  • ADC.WIDTH_12BIT: 12 bit data - this is the default configuration
  • -- Software SPI bus

    There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins, and is accessed via the machine.SPI class: from machine import Pin, SPI # construct an SPI bus on the given pins # polarity is the idle state of SCK # phase=0 means sample on the first edge of SCK, phase=1 means the second spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) spi.init(baudrate=200000) # set the baudrate spi.read(10) # read 10 bytes on MISO spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI buf = bytearray(50) # create a buffer spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI spi.write(b'12345') # write 5 bytes on MOSI buf = bytearray(4) # create a buffer spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf Warning Currently all of sck, mosi and miso must be specified when initialising Software SPI.

    -- Hardware SPI bus

    There are two hardware SPI channels that allow faster transmission rates (up to 80Mhz). These may be used on any IO pins that support the required direction and are otherwise unused (see Pins and GPIO) but if they are not configured to their default pins then they need to pass through an extra layer of GPIO multiplexing, which can impact their reliability at high speeds. Hardware SPI channels are limited to 40MHz when used on pins other than the default ones listed below.
    HSPI (id=1) VSPI (id=2)
    sck 14 18
    mosi 13 23
    miso 12 19
    Hardware SPI has the same methods as Software SPI above: from machine import Pin, SPI hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))

    -- I2C bus

    The I2C driver has both software and hardware implementations, and the two hardware peripherals have identifiers 0 and 1. Any available output-capable pins can be used for SCL and SDA. The driver is accessed via the machine.I2C class: from machine import Pin, I2C # construct a software I2C bus i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) # construct a hardware I2C bus i2c = I2C(0) i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000) i2c.scan() # scan for slave devices i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a buf = bytearray(10) # create a buffer with 10 bytes i2c.writeto(0x3a, buf) # write the given buffer to the slave

    -- Real time clock (RTC)

    See machine.RTC from machine import RTC rtc = RTC() rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time rtc.datetime() # get date and time

    -- Deep-sleep mode

    The following code can be used to sleep, wake and check the reset cause: import machine # check if the device woke from a deep sleep if machine.reset_cause() == machine.DEEPSLEEP_RESET: print('woke from a deep sleep') # put the device to sleep for 10 seconds machine.deepsleep(10000) Notes:
  • Calling deepsleep() without an argument will put the device to sleep indefinitely
  • A software reset does not change the reset cause
  • There may be some leakage current flowing through enabled internal pullups. To further reduce power consumption it is possible to disable the internal pullups: p1 = Pin(4, Pin.IN, Pin.PULL_HOLD) After leaving deepsleep it may be necessary to un-hold the pin explicitly (e.g. if it is an output pin) via: p1 = Pin(4, Pin.OUT, None)
  • -- RMT

    The RMT is ESP32-specific and allows generation of accurate digital pulses with 12.5ns resolution. See esp32.RMT for details. Usage is: import esp32 from machine import Pin r = esp32.RMT(0, pin=Pin(18), clock_div=8) r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8) # The channel resolution is 100ns (1/(source_freq/clock_div)). r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns

    -- OneWire driver

    The OneWire driver is implemented in software and works on all pins: from machine import Pin import onewire ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 ow.scan() # return a list of devices on the bus ow.reset() # reset the bus ow.readbyte() # read a byte ow.writebyte(0x12) # write a byte on the bus ow.write('123') # write bytes on the bus ow.select_rom(b'12345678') # select a specific device by its ROM code There is a specific driver for DS18S20 and DS18B20 devices: import time, ds18x20 ds = ds18x20.DS18X20(ow) roms = ds.scan() ds.convert_temp() time.sleep_ms(750) for rom in roms: print(ds.read_temp(rom)) Be sure to put a 4.7k pull-up resistor on the data line. Note that the convert_temp() method must be called each time you want to sample the temperature.

    -- NeoPixel driver

    Use the neopixel module: from machine import Pin from neopixel import NeoPixel pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels np[0] = (255, 255, 255) # set the first pixel to white np.write() # write data to all pixels r, g, b = np[0] # get first pixel colour For low-level driving of a NeoPixel: import esp esp.neopixel_write(pin, grb_buf, is800khz) Warning By default NeoPixel is configured to control the more popular 800kHz units. It is possible to use alternative timing to control other (typically 400kHz) devices by passing timing=0 when constructing the NeoPixel object.

    -- Capacitive touch

    Use the TouchPad class in the machine module: from machine import TouchPad, Pin t = TouchPad(Pin(14)) t.read() # Returns a smaller number when touched TouchPad.read returns a value relative to the capacitive variation. Small numbers (typically in the tens) are common when a pin is touched, larger numbers (above one thousand) when no touch is present. However the values are relative and can vary depending on the board and surrounding composition so some calibration may be required. There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13 14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ValueError. Note that TouchPads can be used to wake an ESP32 from sleep: import machine from machine import TouchPad, Pin import esp32 t = TouchPad(Pin(14)) t.config(500) # configure the threshold at which the pin is considered touched esp32.wake_on_touch(True) machine.lightsleep() # put the MCU to sleep until a touchpad is touched For more details on touchpads refer to Espressif Touch Sensor.

    -- DHT driver

    The DHT driver is implemented in software and works on all pins: import dht import machine d = dht.DHT11(machine.Pin(4)) d.measure() d.temperature() # eg. 23 (°C) d.humidity() # eg. 41 (% RH) d = dht.DHT22(machine.Pin(4)) d.measure() d.temperature() # eg. 23.6 (°C) d.humidity() # eg. 41.3 (% RH)

    -- WebREPL (web browser interactive prompt)

    WebREPL (REPL over WebSockets, accessible via a web browser) is an experimental feature available in ESP32 port. Download web client from https://github.com/micropython/webrepl (hosted version available at http://micropython.org/webrepl), and configure it by executing: import webrepl_setup and following on-screen instructions. After reboot, it will be available for connection. If you disabled automatic start-up on boot, you may run configured daemon on demand using: import webrepl webrepl.start() # or, start with a specific password webrepl.start(password='mypass') The WebREPL daemon listens on all active interfaces, which can be STA or AP. This allows you to connect to the ESP32 via a router (the STA interface) or directly when connected to its access point. In addition to terminal/command prompt access, WebREPL also has provision for file transfer (both upload and download). The web client has buttons for the corresponding functions, or you can use the command-line client webrepl_cli.py from the repository above. See the MicroPython forum for other community-supported alternatives to transfer files to an ESP32 board.